package com.gt.quality.system.controller;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import com.gt.quality.system.entity.SysFileInfo;
import com.gt.quality.base.pojo.Resp;
import com.gt.quality.system.service.SysFileInfoService;
import com.gt.quality.system.service.excel.SysExcelExportFileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;

/**
 * 文件上传接口
 * @author Administrator
 */
@RestController
@RequestMapping("sysFile")
@Tag(name = "文件管理接口")
@Slf4j
public class FileManagerController {


    private SysFileInfoService sysFileInfoService;

    @Autowired
    public void setSysFileInfoService(SysFileInfoService sysFileInfoService) {
        this.sysFileInfoService = sysFileInfoService;
    }

    private SysExcelExportFileService sysExcelExportFileService;

    @Autowired
    public void setSysExcelExportFileService(SysExcelExportFileService sysExcelExportFileService) {
        this.sysExcelExportFileService = sysExcelExportFileService;
    }

    @PostMapping(value = "/api/upload")
    @Operation(summary = "文件系统上传文件")
    public Resp<Object> uploadFile(@RequestParam("file") MultipartFile file) {
        return Resp.ok(sysFileInfoService.saveFileInfo(file));
    }

    /**
     * 文件系统下载文件
     */
    @GetMapping("/api/download")
    @Operation(summary = "文件系统下载文件")
    public void htmlDownload(@RequestParam("fileId") Long fileId, HttpServletResponse response) throws IOException {
        SysFileInfo fileInfo = sysFileInfoService.getById(fileId);
        String currentFileUrl = fileInfo.getFilePath();
        File realFile = new File(currentFileUrl);
        try (InputStream inputStream = new FileInputStream(realFile);
             ServletOutputStream outputStream = response.getOutputStream();) {
            String fileName = DateUtil.format(LocalDateTime.now(), DatePattern.CHINESE_DATE_PATTERN).concat(fileInfo.getRemark());
            // 设置Content-Disposition响应头，使得浏览器触发文件下载
            response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
            // 设置响应的内容类型
            response.setContentType("application/octet-stream");
            IoUtil.copy(inputStream, outputStream);
        } catch (Exception e) {
            log.error("导出失败", e);
        }
    }

    @GetMapping("/api/downloadV2")
    @Operation(summary = "文件系统下载大文件")
    public void outputWebClient(@Param("fileId") String fileId, HttpServletResponse response) throws Exception {
        SysFileInfo fileInfo = sysFileInfoService.getById(fileId);
        // 获取本地文件
        File file = new File(fileInfo.getFilePath());
        String fileName = file.getName();
        // 文件读取流
        try (FileInputStream fileInputStream = new FileInputStream(file)) {
            // 文件不走缓冲区--直接写入Http输出流
            response.reset();
            response.setContentType("application/octet-stream");
            // 设置文件下载方式
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
            // 获取servlet输出流
            ServletOutputStream outputStream = response.getOutputStream();
            // 定义缓冲区
            byte[] bytes = new byte[1024];
            int len;
            while ((len = fileInputStream.read(bytes)) > 0) {
                outputStream.write(bytes, 0, len);
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }


    /**
     * Description: 数据库导入excel|完成时获取文件全限定名
     *
     * @author: 测试用例
     */
    public String filePathGet(String pathDefaultProxy) throws InterruptedException {
        // 构建文件保存路径
        File file = new File(pathDefaultProxy);
        if (!file.exists()) {
            boolean resp = file.mkdirs();
            log.info(resp ? "创建文件夹成功" : "文件创建失败");
        }
        // 替换本地导出数据条数,一般使用查询条件实际查询出条数
        int totalSize = 1000000;
        // 实体Class|
        boolean asy = sysExcelExportFileService.dataRepeatedWriteManySheetAsy(Object.class, pathDefaultProxy, totalSize, "用户信息");
        if (asy) {
            log.info("文件导入完成.....");
        }
        return pathDefaultProxy;
    }

}
